package impl

import (
	"context"
	"errors"
	"wms/entity"
	"wms/service/model"
	"wms/service/request"
	"wms/util"

	"github.com/acmestack/gorm-plus/gplus"
)

type AttrService struct {
}

var AttrSrvImpl AttrService

func (s *AttrService) List(ctx context.Context, arg any) []*model.Attr {
	attrs, resultDb := gplus.SelectList[entity.Attr](nil)
	if resultDb.Error != nil {
		panic("sql err" + resultDb.Error.Error())
	}

	attrids := make([]int64, len(attrs))
	for i, item := range attrs {
		attrids[i] = item.AttrID
	}

	avMap := make(map[int64][]*model.AttrValue)
	// 查询子表
	query, av := gplus.NewQuery[entity.AttrValue]()
	query.In(&av.AttrID, attrids)
	attrvals, _ := gplus.SelectList[entity.AttrValue](query)

	for _, attrval := range attrvals {
		vlist, e1 := avMap[attrval.AttrID]
		if !e1 {
			vlist = make([]*model.AttrValue, 0)
		}
		_m := new(model.AttrValue)
		util.CopyStruct(_m, attrval)
		vlist = append(vlist, _m)
		avMap[attrval.AttrID] = vlist
	}

	attrListOut := make([]*model.Attr, 0, len(attrs))
	for _, attr := range attrs {
		_s := new(model.Attr)
		util.CopyStruct(_s, attr)
		// 补充对应数据
		_s.Val = avMap[attr.AttrID]
		attrListOut = append(attrListOut, _s)
	}

	return attrListOut
}

func (s *AttrService) Add(ctx context.Context, arg *request.AddAttrRequest) error {
	query, u := gplus.NewQuery[entity.Attr]()
	query.Eq(&u.AttrName, arg.AttrName)
	attr, resultDb := gplus.SelectOne(query)
	if resultDb.RowsAffected > 0 {
		return errors.New("编码:" + arg.AttrName + "已存在")
	}
	attr = new(entity.Attr)
	util.CopyStruct(attr, arg)
	//
	resultDb = gplus.Insert(attr)
	if resultDb.Error != nil {
		return errors.New("insert attr err:" + resultDb.Error.Error())
	}
	util.Log("attr id:", attr.AttrID)
	return nil
}

func (s *AttrService) Edit(ctx context.Context, arg *request.EditAttrRequest) error {
	//
	attr := entity.Attr{AttrID: arg.AttrID, AttrName: arg.AttrName}
	if arg.AttrID > 0 {
		// update
		if arg.IsChangedAttrName {
			_ = gplus.UpdateById(&attr)
		}
		// 定义函数
		getIds := func(l []*entity.AttrValue) []int64 {
			ids := make([]int64, 0, len(l))
			for i := 0; i < len(l); i++ {
				ids = append(ids, l[i].AttrValueID)
			}
			return ids
		}
		//
		query, av := gplus.NewQuery[entity.AttrValue]()
		query.Eq(&av.AttrID, arg.AttrID)
		attrvalEntities, _ := gplus.SelectList[entity.AttrValue](query)
		//
		if len(arg.Val) == 0 {
			return nil
		}

		add_list := make([]*entity.AttrValue, 0)
		update_list := make([]*entity.AttrValue, 0)

		entity_ids := getIds(attrvalEntities)
		entity_ids_map := util.SliceToKeyMap[int64](entity_ids)
		entity_ids_map_del := util.SliceToKeyMap[int64](entity_ids)

		for _, t_val := range arg.Val {
			if t_val.AttrValueID < 1 {
				_av := &entity.AttrValue{AttrID: arg.AttrID, AttrValueName: t_val.AttrValueName}
				add_list = append(add_list, _av)
			} else {
				_, ok := entity_ids_map[t_val.AttrValueID]
				if ok {
					// 存在更新
					_av := &entity.AttrValue{
						AttrValueID:   t_val.AttrValueID,
						AttrID:        arg.AttrID,
						AttrValueName: t_val.AttrValueName}
					update_list = append(update_list, _av)
					delete(entity_ids_map_del, t_val.AttrValueID)
				} else {
					// 不存在, 忽略这个异常
				}
			}
		}

		// 新增
		if len(add_list) > 0 {
			_ = gplus.InsertBatch(add_list)
		}
		// 更新
		for _, tmp := range update_list {
			_ = gplus.UpdateById[entity.AttrValue](tmp)
		}
		// 删除
		if len(entity_ids_map_del) > 0 {
			delIds := util.KeyMapToSlice(entity_ids_map_del)
			gplus.DeleteByIds[entity.AttrValue](delIds)
		}

	} else {
		// add
		_ = gplus.Insert(&attr)
		// for add value
		for _, v := range arg.Val {
			gplus.Insert(&entity.AttrValue{AttrID: arg.AttrID, AttrValueName: v.AttrValueName})
		}
	}
	return nil
}
